🎖️GitЯра🎖️
docs/en/developer/contributing.md fix/qr-error-correction (7b45f84f) Text, 3.27 KB
---
title: Contributing
parent: Developer Guide
nav_order: 8
last_updated: 2026-07-08
aliases:
Tff7b72- contributing
Tff7b72- pull-request
Tc9d1d9 - branch-naming
Tc9d1d9---
Tc9d1d9# Contributing
Guidelines for contributing to the Meshtastic Android/Desktop project (a KMP codebase that also compiles for iOS).
Tc9d1d9## Branch Naming
Branches use conventional-commit style prefixes:
| Prefix | Use for |
|--------|---------|
| Ta5d6ff`feat/<scope>` | New user-visible behavior |
| Ta5d6ff`fix/<scope>` | Bug fixes |
| Ta5d6ff`refactor/<scope>` | Code structure changes |
| Ta5d6ff`chore/<scope>` | Tooling, deps, CI, cleanup |
| Ta5d6ff`docs/<scope>` | Documentation only |
| Ta5d6ff`build/<scope>` | Build system changes |
| Ta5d6ff`ci/<scope>` | CI workflow changes |
| Ta5d6ff`test/<scope>` | Test additions or fixes |
| Ta5d6ff`deps/<scope>` | Dependency updates |
Timestamp-based spec prefixes (Ta5d6ff`YYYYMMDD-HHMMSS-feature-name`, as created by Ta5d6ff`/speckit.git.feature`) are also valid for spec-driven work.
Examples:
Tff7b72- Ta5d6ff`feat/desktop-ble-transport`
Tff7b72- Ta5d6ff`fix/bluetooth-reconnect`
Tff7b72- Ta5d6ff`20260601-074653-air-quality-telemetry`
Tc9d1d9## Development Workflow
Tff7b721. **Fork** the repository (external contributors) or create a branch (maintainers).
Tff7b722. **Implement** your changes following the architecture guidelines.
Tff7b723. **Test** locally: Ta5d6ff`./gradlew spotlessCheck detekt kmpSmokeCompile test allTests`
Tff7b724. **Commit** with clear, descriptive messages.
Tff7b725. **Push** and open a Pull Request.
Tc9d1d9## Commit Messages
Follow conventional commit style:
Ta5d6ff```
feat(docs): add in-app documentation browser
fix(ble): handle reconnection timeout
refactor(navigation): migrate to typed routes
test(search): add keyword ranking tests
```
Tc9d1d9## Pull Request Checklist
Before submitting:
Tff7b72- Tff7b72[ ] Code compiles on all targets: Ta5d6ff`./gradlew kmpSmokeCompile`
Tff7b72- Tff7b72[ ] All tests pass: Ta5d6ff`./gradlew allTests`
Tff7b72- Tff7b72[ ] Code style passes: Ta5d6ff`./gradlew spotlessCheck`
Tff7b72- Tff7b72[ ] Static analysis passes: Ta5d6ff`./gradlew detekt`
Tff7b72- Tff7b72[ ] New code has appropriate test coverage
Tff7b72- Tff7b72[ ] No Ta5d6ff`android.*` imports in Ta5d6ff`commonMain`
Tff7b72- Tff7b72[ ] Koin modules registered if new DI is added
Tff7b72- Tff7b72[ ] Routes added to Ta5d6ff`Routes.kt` if new navigation is introduced
Tff7b72- Tff7b72[ ] Documentation updated if user-facing behavior changes
Tc9d1d9## Code Style
Tff7b72- **Formatting:** Enforced by Spotless (KtLint rules)
Tff7b72- **Static analysis:** Detekt with project-specific configuration
Tff7b72- **Imports:** No wildcard imports; organized automatically by Spotless
Tff7b72- **Line length:** 120 characters maximum
Run formatting:
Ta5d6ff```Ta5d6ffbash
./gradlew spotlessApply
Ta5d6ff```
Tc9d1d9## Architecture Rules
Tff7b72- Feature modules must not depend on other feature modules
Tff7b72- Ta5d6ff`commonMain` must not contain Ta5d6ff`android.*`, Ta5d6ff`java.io.*`, or platform-specific imports
Tff7b72- Prefer interface + DI over Ta5d6ff`expect`/Ta5d6ff`actual` for complex platform behaviors
Tff7b72- All navigation routes must be Ta5d6ff`@Serializable` and defined in Ta5d6ff`Routes.kt`
Tff7b72- Use Koin annotations (Ta5d6ff`@Single`, Ta5d6ff`@Factory`, Ta5d6ff`@Module`) for dependency injection
Tc9d1d9## Verification
Full pre-merge verification:
Ta5d6ff```Ta5d6ffbash
./gradlew spotlessCheck detekt kmpSmokeCompile Tffa657test allTests
Ta5d6ff```
For docs-specific changes, also run:
Ta5d6ff```Ta5d6ffbash
./gradlew generateDocsBundle validateDocsBundle
Ta5d6ff```
Tc9d1d9## Getting Help
Tff7b72- [Tff7b72Meshtastic Discord](Te6edf3https://discord.gg/meshtastic) — Ta5d6ff`#app-development` channel
Tff7b72- GitHub Issues — for bug reports and feature requests
Tff7b72- GitHub Discussions — for questions and ideas
---
Served by rngit 1.5.0 - Generated in 0.09s